#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED

#include <wx/app.h>
#include <wx/grid.h>
#include <wx/frame.h>
#include "bonusMain.h"
#include <wx/tokenzr.h>
#include <wx/datetime.h>
#include <wx/file.h>
#include <wx/wfstream.h>
#include <wx/msgdlg.h>
#include <wx/fileconf.h>
#include "toolkit.h"
#include <wx/dynarray.h>
#include <wx/button.h>
#include <wx/gdicmn.h>
#include "GlobalEvtHandler.h" //包含事件处理类
#include <wx/hashmap.h>
#include <wx/hash.h>
#include <wx/strconv.h>
#include <wx/combobox.h>
#include <wx/checkbox.h>
#include <wx/valtext.h>
#include <wx/hash.h>
#include <wx/url.h>
#include <wx/sstream.h>
#include <curl/curl.h>
#include <wx/choicdlg.h>


#include <wx/msw/registry.h>
#include "DoubleBallGridCellRenderer.h"
#include "DBGrid.h"
#include "doubleball.h"
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;


//#include <boost/algorithm/string.hpp>

//#include <boost/intrusive/hashtable.hpp>
//#include <boost/functional/hash.hpp>
//#include <ecl/ecl.h>

#define MAX_BUF      65536*10*2
#define CURL_STATICLIB
#define SMALLFONT wxFont(10, wxFONTFAMILY_DEFAULT ,wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT , false, wxT("simsun"))
#define NORMALFONT wxFont(12, wxFONTFAMILY_DEFAULT ,wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD , false, wxT("simsun"))

WX_DECLARE_STRING_HASH_MAP( wxString, redBallHashMap );
WX_DECLARE_STRING_HASH_MAP( int, switchHashMap);
WX_DECLARE_STRING_HASH_MAP(wxArrayString,fakeHTable);
const static wxString APP_NAME=wxT("唵 英乍尼 木看 乍玛利 梭哈 196 142857");
//默认返回百分比，不是数字
float forecastMatch(redBallHashMap map,wxArrayString real,bool isnumber=false);
//返回匹配的数字
wxArrayString forecastMatch(wxArrayString real1,wxArrayString real);

//返回没有预测中的红球
wxArrayString forecastMatchMiss(redBallHashMap map,wxArrayString real);
wxArrayString forecastMatchMiss(wxArrayString real1,wxArrayString real2);

void myLog(wxString log);
void debug(wxString log);
const static int MAXREDBALL=33;
const static int MAXBLUEBALL=16;
const static int REDBALLNUMBER=6;
const static   int DBHISTORY_COLS=9;
//define normal rules class
class guessRules
{
 public:
   wxString name;
   vector< int > result;
   ~guessRules()
    {
     result.clear();
    }
};
//define each ball properties
class BALL
{
 public:
//   bool isHigh();//是否最大数
//   bool isLow();//是否最小数
//   bool isLonely();//是否孤单数
//   wxString getCouple();//得到相亲数
//   bool isPrime();//是否质数
//   bool isEven () ;//是否偶数
//   bool isOdd();//是否气数

private:
   int value;
   bool ishigh,islow,islonely,isprime,iseven,isodd;
   vector< wxString > rules;//改数字符合的规律数目
public:

   BALL(int v = 0)
    {
    value = v;
  ishigh=false,islow=false,islonely=false,isprime=false,iseven=false,isodd=false;
    }
   void setValue(int v)
    {
     value = v;
    }
   int getValue()
    {
     return value;
    }
    //
   bool isHigh()//是否最大数
    {
     return ishigh;
    }
   void setHigh(bool v)//是否最大数
    {
     ishigh =v;
    }

    //
   bool isLow()//是否最小数
    {
     return islow;
    }
   void setLow(bool v)
    {
     islow = v;
    }
   //
   bool isLonely()//是否孤单数
   {
    return islonely;
   }
   void setLonely(bool v)
   {
    islonely = v;
   }

   wxString getCouple()//得到相亲数
    {
     return wxEmptyString;
    }
   bool isPrime()//是否质数
    {
     if(value != 0 && value != 1)
       {
         if(value == 2 || value == 3 || value ==5 || value ==7 || value ==11 ||value ==13
            ||value == 17||value ==19 ||value ==23 || value ==29 ||value ==31 )
          {
            return true;
          }
       }
     return false;
    }
   bool isEven () //是否偶数
   {
    if(value !=0 && value%2 == 0) return true;
    return false;
   }
   bool isOdd()//是否奇数
   {
   if(value !=0 && value%2 != 0) return true;
   return false;
   }
};
wxString arrary2string(wxArrayString str);
wxString arrary2string(int* num,int len);

class Statistics:public wxObject
{
public:
        long min;
        long max;
        switchHashMap continuum;//连续号几次数统计
        int numberCount[MAXREDBALL];//统计每个数字的出现频率
        int numberMaxCount[MAXREDBALL];
        int numberMinCount[MAXREDBALL];
        int numberBlueCount[MAXBLUEBALL];
        wxString numberCountStr[MAXREDBALL];//统计每个数字的出现频率,可能有多个相同
        wxArrayString Section01_09;
        wxArrayString Section10_19;
        wxArrayString Section20_29;
        wxArrayString Section30_33;

Statistics()
  {
      min=0;
      max=0;
  for(int i=0;i<MAXREDBALL;i++)
  {
    numberCount[i]=0;
    numberMaxCount[i]=0;
    numberMinCount[i]=0;
  }
//blue ball
  for(int i=0;i<MAXBLUEBALL;i++)
  {
      numberBlueCount[i]=0;
  }

  };
void Sorting(int value)
{
// wxMessageBox(wxString::Format(wxT("%02d"),value));
 if(value>=1 && value<=9)Section01_09.Add(wxString::Format(wxT("%02d"),value));
 if(value>=10 && value<=19)Section10_19.Add(wxString::Format(wxT("%02d"),value));
 if(value>=20 && value<=29)Section20_29.Add(wxString::Format(wxT("%02d"),value));
 if(value>=30 && value<=33)Section30_33.Add(wxString::Format(wxT("%02d"),value));
};
void Blue(int value)
{
 numberBlueCount[value]++;
};
/*
得到所有历史
*/
wxArrayString getHistoryBlueNumbers()
{
  wxArrayString result;
  for(int i=0;i<MAXBLUEBALL;i++)
    {
    if(numberBlueCount[i]>0)result.Add(wxString::Format(wxT("%02d"),i+1));
    }
return result;
}
/*得到结果集合中红球出现的个数*/
wxArrayString getHistoryNumbers()
{
  wxArrayString result;
  for(int i=0;i<MAXREDBALL;i++)
    {
    if(numberCount[i]>0)result.Add(wxString::Format(wxT("%02d"),i+1));
    }
return result;
}
//得到未出的红球
wxArrayString getMissRedsLimitBlue()
{
  wxArrayString result;
  for(int i=0;i<MAXBLUEBALL;i++)
    {
    if(numberCount[i]==0)result.Add(wxString::Format(wxT("%02d"),i+1));

    }
return result;
}
/*得到出现次数最多的红球数*/
int getMaxRedball()
{
 int maxint=0;
   for(int i=0;i<MAXREDBALL;i++)
    {
    if(numberCount[i]>0)//has happend
    {
        if(maxint==0)
        {
         maxint=i;
        }else if(numberCount[i]>numberCount[maxint])
        {
           maxint =i;
        }

    }

    }
 return maxint+1;
}
/*得到出现次数最多的红球数,可能不止一个*/
wxString getMaxRedballs(int red)//red ball
{
wxArrayString result;
int maxcount=0;
 int maxint=0;
   for(int i=0;i<MAXREDBALL;i++)
    {
     if(i==(red-1))continue;//self skip
    if(numberCount[i]>0)//has happend
    {
        if(maxint==0)
        {
         maxint=i;
        }else if(numberCount[i]>numberCount[maxint])
        {
          result.Empty();
          result.Add(wxString::Format(wxT("%02d"),i+1));
           maxint =i;
           maxcount=numberCount[i];
        }else if (numberCount[i]==numberCount[maxint] && numberCount[i]>1)
         {
         result.Add(wxString::Format(wxT("%02d"),i+1));
         }
    }

    }
    if(maxcount==0)return wxEmptyString;
       result.Add(wxString::Format(wxT("(%02d)"),maxcount));
  return arrary2string(result);
}


};
enum
{
     ID_BUTTON_COPYCLIPBOARD=20000,
     ID_BUTTON_FIRSTPAGE=200001,
     ID_BUTTON_FORM_PAGE=200002,
     ID_BUTTON_NEXT_PAGE=200003,
     ID_BUTTON_LAST_PAGE=200004,
     ID_BUTTON_PRINT_PAGE=200005,
     ID_BUTTON_TO_CLIP=200006
};
wxString testCaseLS();

wxString AJAX(wxString url);
wxString AJAX(wxString host,wxString url);
wxString AJAXBycurl(wxString url);
void createHistoryGrid(bonusFrame* frame);
void   createSystemLogger(bonusFrame* frame);
         wxString getDefaultConfigPath();
         wxString getConfigFileDir();
         wxString readConfigItem(wxString key);
         bool checkDatabase();
 wxArrayString  checkAIStrategyClass();
 wxArrayString  checkAIStrategyName();
  wxString getLastTermOrder();//得到最后一期期号
  wxString getLastTermDate();//得到最后一期期号日期
wxString getNextTermOrder(wxString cOrder);
wxString getNextTermDate(wxString cTerm);
bool CHECK_YEAR_CHANGE(wxString termdate);
wxString formatDBtoHTML(DoubleBall *db,bool compact=false);//格式化_dbhistory
wxString formatLISPtoHTML(DoubleBall *db);//格式化_LISPLET 表格
wxString formatGridtoHTML(wxGrid * grid,int startrow,int offset,int pagenumber=33);//格式化_dbhistory成HTML模拟GRID
wxString  formatArraytoHTML(wxArrayString result);
wxString formatNotestoHTML(DoubleBall *db);//格式化_notes表
wxString formatDBtoHTMLGrid(DoubleBall *db,int pagerows=33);//格式化_dbhistory
wxString formatDBtoHTMLTable(DoubleBall *db,int wrap=16,int defaultwrap=16);//格式化_dbhistory

//anylyst
wxString getMissDistance(wxString term=wxEmptyString);
wxString getDigitsTrendAnalyst(wxString term,int offset);
wxArrayString getSelectedGridRowRedBall(wxGrid* grid,int offset=0);

wxString getSelectedGridRowTerm(wxGrid * grid,int offset=0);//得到当前行的期
wxString getSelectedGridRowBlueBall(wxGrid * grid,int offset=0);//得到当前行的篮球

void setArraytoGridLine(wxGrid* grid,wxArrayString redball,int row);


wxString hashmap2string(redBallHashMap hm);
wxString hashmap2string(switchHashMap hm);
wxString hashmap2html(switchHashMap hm);
wxString statis2string(DoubleBall *db,Statistics* st,wxString AIsql=wxEmptyString,bool display=false);

wxArrayString hashmap2array(switchHashMap hm);
wxString bothInclude(switchHashMap distance,switchHashMap sum);//发现重复的key
//显示一个HTML窗口,info是信息
int showHTMLMessage(wxString info);
void displayForecast(wxArrayString current,wxArrayString forcast,wxString cTerm,wxString ployName);

static const wxString config = wxT("\\Config.ini");
//static const wxString VERSION =_T("(2010.9.11)");
static const wxString VERSION =_T("(2013.2.27)");
static const wxString appAbout(
_T("<html><body bgcolor='#FFFFFF'>")
_T("<table cellspacing=3 cellpadding=4 width='100%'>")
_T("<tr><td bgcolor='#101010'>")
_T("<center> <font size=+2 color='#FFFFFF'><b><br>双色球大富翁(2013.2.27)")
_T("<br></b>")
_T("</font></center>")
_T("</td></tr><tr>")
_T("<td bgcolor='#73A183'> <b><font size=+1>版权所有(2009)</font></b><p>")
_T("<font size=-1><table cellpadding=0 cellspacing=0 width='100%'>")
_T("<tr><td width='65%'>")
_T("<h2>William Wang</h2><p>")
_T("<B>F1:Help<p>")
_T("F2:Log窗口<p>")
_T("F3:分析窗口<p>")
_T("F4:篮球分析<p>")
_T("F5:红球分割<p>")
_T("F6:历史纪录匹配<p>")
_T("F7:匹配重复4,5个红球<p>")
_T("F8:...</B><p>")
_T("</td><td valign=top>")
_T("</td></tr> </table><font size=1>wxWidgets 开发 </font> </font> </td> </tr></table></body></html>")
);
//toolbar history search
extern wxComboBox*	m_comboBox1;
extern wxComboBox*	m_comboBox2;
extern wxComboBox*	m_comboBox3;
extern wxComboBox*	m_comboBox4;
extern wxComboBox*	m_comboBox5;
extern wxComboBox*	m_comboBox6;
extern wxComboBox*	blue_combobox;

extern wxCheckBox* positionStrict;
extern wxComboBox* watchNext;
extern wxHtmlWindow* historywin;



//3X3 Matrix
wxString formatLUOSHU9(wxArrayString match);
static const wxString LUOSHU9[][3] ={
    {wxT("8"),wxT("6"),wxT("1")},
    {wxT("3"),wxT("5"),wxT("7")},
    {wxT("4"),wxT("9"),wxT("2")}
};

wxString formatLUOSHU16(wxArrayString match);

//4x4 Matrix
static const wxString LUOSHU16[][4] ={
    {wxT("01"),wxT("15"),wxT("14"),wxT("04")},
    {wxT("12"),wxT("06"),wxT("07"),wxT("09")},
    {wxT("08"),wxT("10"),wxT("11"),wxT("05")},
    {wxT("13"),wxT("03"),wxT("02"),wxT("16")}
};
//5X5 Matrix
static const wxString LUOSHU25[][5] ={
        {wxT("17"),wxT("24"),wxT("01"),wxT("08"),wxT("15")},
        {wxT("23"),wxT("05"),wxT("07"),wxT("14"),wxT("16")},
        {wxT("04"),wxT("06"),wxT("13"),wxT("20"),wxT("22")},
        {wxT("10"),wxT("12"),wxT("19"),wxT("21"),wxT("03")},
        {wxT("11"),wxT("18"),wxT("25"),wxT("02"),wxT("09")}

};
wxPoint getLUOSHU36RedBallCoordinate(wxString redball);
wxString formatDB2LUOSHU36(DoubleBall *db,int PageSize=15);//格式化结果集合为洛数
wxString DB2SingleCollect(DoubleBall *db);//格式化结果集合为洛数
wxString formatLUOSHU36(wxArrayString match,bool big);
wxString formatLUOSHU36(wxArrayString match,wxArrayString formermatch,bool big);//上一期的红球和本期红球
wxString formatLUOSHU36WithSurround(wxArrayString match,redBallHashMap surround,bool big);
wxString formatLUOSHU36InALL(wxArrayString match);
wxString formatLUOSHU36WithPredict(wxArrayString match,wxArrayString pred);
//get redball surrond matrix number
redBallHashMap findLUOSHU36SurroundMatrix(wxArrayString redball);
wxArrayString killLUOSHU36SurroundMatrix(redBallHashMap redball);
wxString getLUOSHU36Value(int row,int col);
//6X6 Matrix
static const wxString LUOSHU36[][6] =
{
        {wxT("01"),wxT("09"),wxT("34"),wxT("33"),wxT("32"),wxT("02")},
        {wxT("06"),wxT("11"),wxT("25"),wxT("24"),wxT("14"),wxT("31")},
        {wxT("10"),wxT("22"),wxT("16"),wxT("17"),wxT("19"),wxT("27")},
        {wxT("30"),wxT("18"),wxT("20"),wxT("21"),wxT("15"),wxT("07")},
        {wxT("29"),wxT("23"),wxT("13"),wxT("12"),wxT("26"),wxT("08")},
        {wxT("35"),wxT("28"),wxT("03"),wxT("04"),wxT("05"),wxT("36")}
};
static const wxString REDBALLS[]=
{
wxT(""), wxT("01"),wxT("02"),wxT("03"),wxT("04"),wxT("05"),wxT("06"),wxT("07"),wxT("08"),wxT("09"),
 wxT("10"),wxT("11"),wxT("12"),wxT("13"),wxT("14"),wxT("15"),wxT("16"),wxT("17"),wxT("18"),wxT("19"),
 wxT("20"),wxT("21"),wxT("22"),wxT("23"),wxT("24"),wxT("25"),wxT("26"),wxT("27"),wxT("28"),wxT("29"),
 wxT("30"),wxT("31"),wxT("32"),wxT("33")
};
static const wxString listStype[]=
{
 wxT("幻方方式"),wxT("列表方式"),wxT("Grid方式")
};
static const wxString BLUEBALLS[]=
{
wxT(""), wxT("01"),wxT("02"),wxT("03"),wxT("04"),wxT("05"),wxT("06"),wxT("07"),wxT("08"),wxT("09"),
 wxT("10"),wxT("11"),wxT("12"),wxT("13"),wxT("14"),wxT("15"),wxT("16")
};
static const long PrimeMagicSize=9;
static const long PrimeMagic[]={05,07,11,13,17,19,23,27,29,31};
//平方数字
static const long squareMagicSize=4;
static const long squareMagic[]={04,9,16,26};

extern  bonusFrame* BFrame;
extern bool  __DEBUG;
extern  int GRID_ROW;//
extern  int GRID_COL;//
#define BIGFONT   wxFont(18, wxDEFAULT, wxNORMAL, wxFONTWEIGHT_BOLD, 0, wxT("Sans"))
//策略分析的功能函数
void findMatchRedBall();
fakeHTable  findContinuum(wxArrayString form);

wxArrayString findLessThanTen(wxArrayString from);//发现小于10的红球
int  getRightDistance(wxArrayString from);//得到最右边两个红球距离
wxString getMaxRedball(wxArrayString nums);//得到最大红球
wxString getMinRedball(wxArrayString nums);//得到最小红球
switchHashMap getRedballDistance(wxArrayString nums);//得到红球间隔数据
switchHashMap getRedballSum(wxArrayString nums);//得到红球和数据
//#include <boost/algorithm/string.hpp>

int getMinRedbalDistance(wxArrayString nums);

//猜测的模式
wxArrayString guessCouble(wxArrayString numbs,int nums);
wxArrayString guessLessThan10(wxArrayString numbs);//猜测最左端数字组合
wxArrayString guessFolk(wxArrayString last);//根据上一期得到应该出的对应数

wxArrayString  guess20101005(wxString term);//猜测某一期数据

wxString FeiCaiTianXia(wxString lastterm);
wxString HongLanQiuBa(wxString lastterm);
wxString LeCaiWang(wxString lastterm);

wxString GetURLerror(wxURL url);
 /*
 * Write data callback function (called within the context of
 * curl_easy_perform.
 */
static size_t write_data( void *buffer, size_t size, size_t nmemb, void *userp );
 static char wr_buf[MAX_BUF+1];
 static int  wr_index=0;
Statistics* statisticsRecords(DoubleBall * db);//统计一次结果集合，得到最大，最小,统计每个数字的统计
wxString formatNumberMate(wxString term,int range=30);//统计一个数字里得到的最多伴侣
Statistics* findNumberMate(wxString term,int range=30);//统计一个数字里得到的最多伴侣
wxString formatALLNumberMate(int range=30);//统计所有红球一个数字里得到的最多伴侣
Statistics* findALLNumberMate(int range=30);//统计所有红球一个数字里得到的最多伴侣

int  getGridRowLine(wxString term);//得到对应期号的行号
string int2str (int n);
string  combine(string * a, int n, int m);
wxArrayString split(wxString str,wxString splitter = wxT(" "));
wxString int2wxString(int n);
wxString GraphOfArray(long values[],long length);
//得到某期数据各个段的数据里的独立数

static int CompareStringLen(const wxString& first, const wxString& second);
Statistics* getSection(wxArrayString termdata);
wxString formatSection(wxArrayString termdata);
wxArrayString getIsolation(wxArrayString termdata);
wxString formatIsolation(wxArrayString termdata);

#endif // GLOBAL_H_INCLUDED
//ECL AI
//void testECL();
